//
//  UIButton+SGExtension.swift
//  QingLiuSwift
//
//  Created by xyanl on 2024/11/1.
//  Copyright © 2024 考拉🐨. All rights reserved.
//

import UIKit

//extension UIButton: SpadgerCompatible {}

public extension Spadger where Base == UIButton {
    
    /// 设置图片位置
    /// - Parameters:
    ///   - imagePlacement: 图片位置
    ///   - imagePadding: 图片与文字的间距
    ///   - contentInsets: 内容的内边距
    @available(iOS 15.0, *)
    func setImagePlacement(_ placement: NSDirectionalRectEdge, _ padding: CGFloat = 0, contentInsets: NSDirectionalEdgeInsets = .zero) {
        // 创建UIButtonConfiguration
        var config = UIButton.Configuration.plain()
        // 设置图像和图像位置
        config.image = base.currentImage
        // 图像放置的位置
        config.imagePlacement = placement
        // 可选：设置图像与文字之间的间距
        config.imagePadding = padding
        // 可选：设置内容的内边距
        config.contentInsets = contentInsets
        // 配置背景图片
        config.background.image = base.currentBackgroundImage
        // 应用配置到按钮
        base.configuration = config
    }
    
    /// 设置按钮的背景色
    /// - Parameters:
    ///   - color: 背景色
    ///   - state: 状态
    func setBackgroundColor(_ color: UIColor, for state: UIControl.State) {
        base.setBackgroundImage(color.toImage(), for: state)
    }
}


// MARK: - UIButton 图片 与 title 位置关系
public extension Spadger where Base: UIButton {
    
    /// 图片的方位
    enum ImagePosition {
        /// 图上，文字下
        case top
        /// 图左，文字右
        case left
        /// 图下，文字上
        case bottom
        /// 图右，文字左
        case right
    }
    
    /// 设置图片的方位
    /// - Parameters:
    ///   - position: 图片的位置
    ///   - padding: 图片和文字的间距
    @discardableResult
    func setImagePosition(_ position: ImagePosition = .left, padding: CGFloat = 0) -> UIButton {
        switch position {
        case .left:
            alignHorizontal(spacing: padding, imageFirst: true)
        case .right:
            alignHorizontal(spacing: padding, imageFirst: false)
        case .top:
            alignVertical(spacing: padding, imageTop: true)
        case .bottom:
            alignVertical(spacing: padding, imageTop: false)
        }
        return base
    }
    
    /// 水平方向
    /// - Parameters:
    ///   - spacing: 间距
    ///   - imageFirst: 图片是否优先
    private func alignHorizontal(spacing: CGFloat, imageFirst: Bool) {
        let edgeOffset = spacing / 2
        base.imageEdgeInsets = UIEdgeInsets(
            top: 0,
            left: -edgeOffset,
            bottom: 0,
            right: edgeOffset
        )
        base.titleEdgeInsets = UIEdgeInsets(
            top: 0,
            left: edgeOffset,
            bottom: 0,
            right: -edgeOffset
        )
        if !imageFirst {
            base.transform = CGAffineTransform(scaleX: -1, y: 1)
            base.imageView?.transform = CGAffineTransform(scaleX: -1, y: 1)
            base.titleLabel?.transform = CGAffineTransform(scaleX: -1, y: 1)
        }
        base.contentEdgeInsets = UIEdgeInsets(top: 0, left: edgeOffset, bottom: 0, right: edgeOffset)
    }
    
    /// 垂直方向
    /// - Parameters:
    ///   - spacing: 间距
    ///   - imageTop: 图片是不是在顶部
    private func alignVertical(spacing: CGFloat, imageTop: Bool) {
        guard let imageSize = self.base.imageView?.image?.size,
              let text = self.base.titleLabel?.text,
              let font = self.base.titleLabel?.font
        else {
            return
        }
        let labelString = NSString(string: text)
        let titleSize = labelString.size(withAttributes: [NSAttributedString.Key.font: font])
        
        let imageVerticalOffset = (titleSize.height + spacing) / 2
        let titleVerticalOffset = (imageSize.height + spacing) / 2
        let imageHorizontalOffset = (titleSize.width) / 2
        let titleHorizontalOffset = (imageSize.width) / 2
        let sign: CGFloat = imageTop ? 1 : -1
        
        base.imageEdgeInsets = UIEdgeInsets(
            top: -imageVerticalOffset * sign,
            left: imageHorizontalOffset,
            bottom: imageVerticalOffset * sign,
            right: -imageHorizontalOffset
        )
        base.titleEdgeInsets = UIEdgeInsets(
            top: titleVerticalOffset * sign,
            left: -titleHorizontalOffset,
            bottom: -titleVerticalOffset * sign,
            right: titleHorizontalOffset
        )
        // increase content height to avoid clipping
        let edgeOffset = (min(imageSize.height, titleSize.height) + spacing) / 2
        base.contentEdgeInsets = UIEdgeInsets(top: edgeOffset, left: 0, bottom: edgeOffset, right: 0)
    }
}


// MARK: - 修改按钮触发范围
extension UIButton {
    
    private static var Expand_Key: Void?
    private static var Touch_Key: Void?
    
    /// 四周扩大范围
    var touchExpand: CGFloat {
        get { (objc_getAssociatedObject(self, &Self.Expand_Key) as? CGFloat) ?? 0.0 }
        set {
            objc_setAssociatedObject(self, &Self.Expand_Key, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
            touchEdgeInsets = UIEdgeInsets(top: newValue, left: newValue, bottom: newValue, right: newValue)
        }
    }
    
    /// 扩展按钮的点击区域
    var touchEdgeInsets: UIEdgeInsets {
        get { (objc_getAssociatedObject(self, &Self.Touch_Key) as? UIEdgeInsets) ?? .zero }
        set { objc_setAssociatedObject(self, &Self.Touch_Key, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY) }
    }
    
    private func expandRect() -> CGRect {
        if touchEdgeInsets != .zero {
            return CGRect(
                x: bounds.origin.x - touchEdgeInsets.left,
                y: bounds.origin.y - touchEdgeInsets.top,
                width: bounds.size.width + touchEdgeInsets.left + touchEdgeInsets.right,
                height: bounds.size.height + touchEdgeInsets.top + touchEdgeInsets.bottom
            )
        } else {
            return bounds;
        }
    }
    
    open override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        let buttonRect = expandRect()
        if buttonRect.equalTo(bounds) {
            return super.point(inside: point, with: event)
        } else {
            return buttonRect.contains(point)
        }
    }
}

extension UIButton {
    
    /// 按钮交互状态, 带有蒙板
    /// - Parameter enabled: true: 可以点击交互，false: 不可交互,会有一层蒙板
    func userInteractionEnabled(_ enabled: Bool) {
        isUserInteractionEnabled = enabled
        subviews.forEach { view in
            if view.isKind(of: UIVisualEffectView.self) {
                view.removeFromSuperview()
            }
        }
        
        if !enabled {
            // 不能交互，加蒙版
            let blurEffect = UIBlurEffect(style: .regular)
            let blurView = UIVisualEffectView(effect: blurEffect)
            blurView.alpha = 0.3
            blurView.frame = bounds
            addSubview(blurView)
        }
    }
}

